home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / listserv5.31 / part02 < prev    next >
Encoding:
Internet Message Format  |  1991-12-13  |  59.9 KB

  1. Subject: v25i036: listserv5.31 - mailing list management system, Part02/06
  2. Newsgroups: comp.sources.unix
  3. Approved: vixie@pa.dec.com
  4.  
  5. Submitted-By: tasos@cs.bu.edu
  6. Posting-Number: Volume 25, Issue 36
  7. Archive-Name: listserv5.31/part02
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line, then unpack
  11. # it by saving it into a file and typing "sh file".  To overwrite existing
  12. # files, type "sh file -c".  You can also feed this as standard input via
  13. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  14. # will see the following message at the end:
  15. #        "End of archive 2 (of 6)."
  16. # Contents:  src/README src/defs.h src/sender.c src/serverd.c
  17. #   src/start.c src/sysmail.c src/sysmail.h
  18. # Wrapped by vixie@cognition.pa.dec.com on Fri Dec 13 18:31:08 1991
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'src/README' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'src/README'\"
  22. else
  23. echo shar: Extracting \"'src/README'\" \(9846 characters\)
  24. sed "s/^X//" >'src/README' <<'END_OF_FILE'
  25. X
  26. X
  27. X                    DISCUSSION LIST SERVER SYSTEM
  28. X                    -----------------------------
  29. X
  30. X             Copyright (c) 1991, Anastasios C. Kotsikonas
  31. X
  32. X                           tasos@cs.bu.edu
  33. X                          Boston University
  34. X                           December 9 1991
  35. X
  36. AGREEMENT: This software can be used and distributed freely as long as you
  37. do not remove or alter the Copyright notice in the file defs.h; this notice
  38. is #define'd in the symbol VERSION. By using this software you are bound
  39. by this agreement.
  40. This software comes with no warranties and cannot be sold for profit.
  41. The AGREEMENT and COPYRIGHT notices should be included in all source
  42. files when distributing this software.
  43. COPYRIGHT: Copyright (c) 1991, Anastasios C. Kotsikonas
  44. X
  45. UPDATES: All updates can be obtained from cs.bu.edu (128.197.10.1) via
  46. anonymous ftp, in the directory pub/listserv. If you downloaded this version
  47. from another ftp site, please keep an eye on cs.bu.edu. Bug fixes will
  48. be posted periodically over there, and no notifications will be posted to
  49. news; you should check the directory periodically.
  50. X
  51. COMPILER: The programs are written with ANSI C function prototypes; if your
  52. compiler cannot handle them, I suggest you also download unproto.tar.Z
  53. from cs.bu.edu; cd pub/unproto; this is a nice set of programs that will
  54. convert ANSI-isms to old style C -- please send any questions about unproto
  55. to its author, not me. There is also a script (oldc -- found in pub/utils)
  56. that will step through all of its input files and use unproto to make the
  57. conversions. For those compilers that die when they see a contol-L in the
  58. source code, I have written a C program that "cleans" source files; it is
  59. called clean.c and can be found in pub/utils as well; compile as follows:
  60. X        % cc -Dunix clean.c -o clean
  61. X
  62. PREPROCESSOR: ANSI C preprocessors complain about the way I concatenate
  63. strings (as is the case with the PATH symbol). This is expected since I
  64. do not conform to ANSI C in this respect. In this case you should
  65. use the script /usr/server/stds; suggested usage is:
  66. X        % stds /usr/server/src/*.h /usr/server/src/*.c
  67. Use this script before compilation, of course. Unfortunately, I cannot
  68. convert to ANSI C string concatenation, because unproto does not work in
  69. this case, and people without ANSI C compilers will be in a lot of trouble.
  70. X
  71. ACKNOWLEDGEMENTS: I would like to thank the following people for their
  72. suggestions and contributions to this package (not all suggestions have
  73. been incorporated):
  74. X1) Bob Boyd (rbn@epavax.rtpnc.epa.gov): IRIX port, gateway connections
  75. X   feedback, 5.3 beta testing.
  76. X2) Stefan Schroer (Stefan.Schroer@cyber.urz.uni-wuppertal.dbp.de): MINIX port,
  77. X   help files, 'get' and 'index' requests.
  78. X3) Scott J. Ellentuch (tuc@stormking.com): IBM R6000 port, enhancements to
  79. X   the farch utility, 5.3 beta testing.
  80. X4) David Warner (warner@austin.onu.edu): IBM R6000 bug fixing, 5.3 beta 
  81. X   testing, tolerance with my obnoxious code -- I owe this gentleman a lot.
  82. X
  83. X            The discussion list server system includes 65 files: 
  84. X
  85. X /usr/server/doc:
  86. X   server.nr    -- the man page for the system (% more server.nr)
  87. X   farch.nr    -- the man page for the file archiving utility
  88. X   queue.nr    -- the man page for tha mail queueing system
  89. X   README    -- instructions for installing the man pages on your system
  90. X
  91. X /usr/server/help:
  92. X   general      -- general help file
  93. X   information  -- help on the information request
  94. X   lists        -- help on the lists request
  95. X   recipients   -- help on the recipients request
  96. X   set          -- help on the set request
  97. X   statistics   -- help on the statistics request
  98. X   subscribe    -- help on the subscribe request
  99. X   unsubscribe  -- help on the unsubscribe request
  100. X   index    -- help on the index request
  101. X   get        -- help on the get request
  102. X   release    -- help on the release request
  103. X
  104. X /usr/server/archives:
  105. X   /usr/server/archives/listserv: Master archive:
  106. X     DIR    -- info on files and directories they are located
  107. X     INDEX    -- master index of all archives (listserv, pub, unix)
  108. X     refcard    -- list of all commands
  109. X     info    -- info on this archive
  110. X     /usr/server/archives/listserv/example.dat:
  111. X       example.dat1    -- part 1 of file example.dat in archive listserv
  112. X       example.dat2    -- part 2 of file example.dat in archive listserv
  113. X       example.dat3    -- part 3 of file example.dat in archive listserv
  114. X   /usr/server/archives/pub: Subarchive of listserv:
  115. X     DIR    -- info on files and directories they are located
  116. X     INDEX    -- index of all archives in this archive
  117. X     info    -- info on this archive
  118. X   /usr/server/archives/pub/unix: Subarchive of pub:
  119. X     DIR    -- info on files and directories they are located
  120. X     INDEX    -- index of files in this archive
  121. X     info    -- info on this archive
  122. X
  123. X /usr/server/src:
  124. X   REGISTRATION    -- registration form for using this software
  125. X   README    -- this file
  126. X   global.h    -- global variables definitions
  127. X   struct.h    -- defines the server structure
  128. X   defs.h    -- general definitions
  129. X   tlock.c    -- tests for locks, i.e. whether any server programs are running
  130. X             on another file system via NFS
  131. X   list.h    -- specific definitions for list.c
  132. X   list.c    -- the list's server
  133. X   listserv.h    -- specific definitions for listserv.c
  134. X   listserv.c    -- server for individual requests
  135. X   pqueue.h    -- specific definitions for pqueue.c
  136. X   pqueue.c    -- processes the mail queue
  137. X   serverd.h    -- specific definitions for serverd.c
  138. X   serverd.c    -- parent program that spawns list or listserv
  139. X   start.h    -- specific definitions for start.c
  140. X   start.c    -- does housekeeping before spawning serverd, makes sure that
  141. X           files exist, kills any running server processes, etc
  142. X   sysmail.h    -- specific definitions for sysmail.c
  143. X   sysmail.c    -- system mailmethod routines
  144. X   signals.c    -- signal processing routines
  145. X   sender.c    -- sender address manipulation routines
  146. X   misc.c    -- general purpose routines
  147. X   farch.c    -- utility for easy archiving of files
  148. X   Makefile    -- to build your own server
  149. X
  150. X /usr/server
  151. X   setup        -- a script to be run before starting for the first time
  152. X   queued    -- daemon controlling the processing of the mail queue
  153. X   peer        -- script to add a peer list
  154. X   news        -- script to add a news group to a list
  155. X   reformat    -- script used to reformat incoming messages (see documentation)
  156. X   stds        -- script used to do string concatenation before compilation
  157. X   redux        -- script that reduces the size of mbox by removing unnecessary
  158. X                   fields from the header of each message
  159. X   ulock        -- in conjunction with the 'flocks' file, this utility
  160. X                   removes all locked files (unlocks them)
  161. X   flocks       -- shell script to remove locked files
  162. X   .awk        -- awk program used for the 'statistics' and 'recipients'
  163. X           listserv requests
  164. X   .stats    -- shell script used for the 'statistics' listserv request
  165. X   .grep    -- shell program used for the 'statistics' listserv request
  166. X   .ignored    -- a list of email addresses whose messages are ignored
  167. X   config    -- the system's configuration file
  168. X
  169. X
  170. X               |-->-----------> START
  171. X               |                  |
  172. X               |                  |
  173. X               ^          (spawns-and-dies)
  174. X               |                  |
  175. X               |                  |
  176. X               |--<--restart--- SERVERD <--shutdown-<--|
  177. X                                  /\                   r
  178. X                                 /  \                  e
  179. X                                /    \                 s
  180. X                    (spawns either one as necessary)   t       
  181. X                              /        \               a
  182. X                             /          \              r
  183. X                           LIST        LISTSERV --->---t
  184. X
  185. X
  186. The diagram shows that 'start' spawns 'serverd' and then dies, and that
  187. X'listserv' may request 'serverd' to die (shutdown) or request that the
  188. system is restarted, in which case 'serverd' spawns 'start' and dies.
  189. X
  190. XEnjoy!
  191. X
  192. Revision history:
  193. X
  194. Version      Date     Status    Comments
  195. X------------------------------------------------------------------------------
  196. X 3.45      12/20/90  Outdated * First public version; bugs with listserv
  197. X 3.67      01/03/91  Outdated   Bugs fixed
  198. X 3.68      01/04/91  Outdated * v3.67 + tlock utility
  199. X 4.0       04/09/91  Exprmntl   v3.68 + STATISTICS listserv command
  200. X 4.1       04/16/91  Outdated   v4.0 + redux utility
  201. X 4.2       05/02/91  Outdated   v4.1 w/ optimized source code, better doc.
  202. X 4.21      05/03/91  Outdated   v4.2 w/ redux which was left out by mistake
  203. X 4.3       05/03/91  Outdated * v4.21 w/ better mailer-daemon msg handling
  204. X 4.4       05/22/91  Exprmntl   v4.3 w/ enhanced tlock,control,start,listserv
  205. X 4.5       06/12/91  Exprmntl   v4.3 w/ enhanced listserv
  206. X 5.0       07/17/91  Outdated * v4.4 + support for multiple lists
  207. X 5.1       08/27/91  Outdated * v5.0 + bug fixes, enhanced listserv
  208. X 5.1 Rev I 10/03/91  Outdated   v5.0 + more bug fixes
  209. X 5.2       10/08/91  Outdated * v5.1 + archives, GET, INDEX requests,
  210. X                        farch utility, moderated lists,
  211. X                       disabled listserv commands on a per list
  212. X                       basis, link with peer lists and news
  213. X                       feeds
  214. X 5.2 Rev A 10/10/91  Outdated   v5.2 + bug fixes
  215. X 5.21      10/15/91  Exprmntl   v5.2A + multiple recipients in one message
  216. X 5.3 beta  10/31/91  Exprmntl   v5.21 + system mailmethod, bug fixes
  217. X 5.3        12/05/91  Outdated * v5.2A + bug fixes, universal system mailmethod,
  218. X                    multiple recipients in one message,
  219. X                    support for blanks in email addresses,
  220. X                    user-set limit on size of messages,
  221. X                    RFC 821 compliant SMTP implementation,
  222. X                    extensive mail loop detection mechanism,
  223. X                    new scripts (stds, reformat), enhanced
  224. X                    GET request, and more.
  225. X 5.31       12/09/91  Released * v5.3 + mail queuing capability/subsystem +
  226. X                       RELEASE request
  227. X
  228. X*These versions have been made public via news.
  229. END_OF_FILE
  230. if test 9846 -ne `wc -c <'src/README'`; then
  231.     echo shar: \"'src/README'\" unpacked with wrong size!
  232. fi
  233. # end of 'src/README'
  234. fi
  235. if test -f 'src/defs.h' -a "${1}" != "-c" ; then 
  236.   echo shar: Will not clobber existing file \"'src/defs.h'\"
  237. else
  238. echo shar: Extracting \"'src/defs.h'\" \(4982 characters\)
  239. sed "s/^X//" >'src/defs.h' <<'END_OF_FILE'
  240. X/*
  241. X  AGREEMENT: This software can be used and distributed freely as long
  242. X  as you do not remove or alter the Copyright notice in this file;
  243. X  this notice is #define'd in the symbol VERSION. Although you may alter
  244. X  the code provided, you may not alter the functions create_header()
  245. X  and create_multi_recipient_header() in list.c and listserv.c.
  246. X  By using this software you are bound by this agreement. 
  247. X  This software comes with no warranties and cannot be sold for profit.
  248. X  The AGREEMENT and COPYRIGHT notices should be included in all source
  249. X  files when distributing this software.
  250. X  COPYRIGHT: Copyright (c) 1991, Anastasios C. Kotsikonas
  251. X
  252. X  General system definitions.
  253. X
  254. X  WARNING: Do not use the gcc preprocessor.
  255. X
  256. X  WARNING: DO NOT CHANGE THE NAME OF THE 'SERVERD', 'LIST' or 'LISTSERV'
  257. X  PROGRAMS in the #define's below. If you do so, make sure that command line
  258. X  options are separated by at least a space from the filename.
  259. X  DO NOT INCLUDE ANY CHARACTERS SUCH AS &, |, <, >. etc.
  260. X
  261. X  Preserve any quotes and new lines that appear below; change only path names.
  262. X
  263. X  ALWAYS SPECIFY ABSOLUTE PATHS.
  264. X
  265. X*/
  266. X
  267. X#define VERSION          "5.31 -- Copyright (c) 1991, Anastasios Kotsikonas"
  268. X#define PATH              "/usr/server
  269. X#define COMPLETE_FILE(f)  fprintf (f, "\n.\nQUIT\n")
  270. X#define TELNET          "telnet `hostname` 25 > /dev/null 2>&1 "
  271. X#define BINMAIL          "/bin/mail > /dev/null 2>&1"
  272. X#define INEWS          "/usr/lib/news/inews"
  273. X#define SUBSCRIBERS       ".subscribers"
  274. X#define ALIASES          ".aliases"
  275. X#define NEWSF          ".news"
  276. X#define PEERS          ".peers"
  277. X#define HEADERS          ".headers"
  278. X#define RESTRICTED        ".restricted"
  279. X#define IGNORED           ".ignored"
  280. X#define INFO_FILE         ".info"
  281. X#define WELCOME_FILE      ".welcome"
  282. X#define REPORT_LIST       ".report.list"
  283. X#define WARNING          PATH/.warning"
  284. X#define REPORT_SERVER     PATH/.report.server"
  285. X#define REPORT_SERVERD    PATH/.report.daemon"
  286. X#define REPORT_PQUEUE      PATH/.report.pqueue"
  287. X#define CONFIG          PATH/config"
  288. X#define LIST              PATH/list -1 -L "
  289. X#define SERVER            PATH/listserv -1 "
  290. X#define LIST_MAIL_FILE      "mail"
  291. X#define LIST_MODERATED_F  "moderated"
  292. X#define MESSAGE_IDS_F     ".message.ids"
  293. X#define SERVER_MAIL_FILE  PATH/requests"
  294. X#define SERVERD           PATH/serverd"
  295. X#define PQUEUE          PATH/pqueue"
  296. X#define START          PATH/start"/* Do not give ANY command line options */
  297. X#define START_OPTIONS      "-cr"        /* provide them here */
  298. X#define SERVERD_LOCK_FILE PATH/.lock.serverd"
  299. X#define LIST_LOCK_FILE    PATH/.lock.list"
  300. X#define SERVER_LOCK_FILE  PATH/.lock.server"
  301. X#define PQUEUE_LOCK_FILE  PATH/.lock.pqueue"
  302. X#define PID_PQUEUE      PATH/.pid.pqueue"
  303. X#define PID_SERVERD      PATH/.pid.daemon"
  304. X#define PID_SERVER      PATH/.pid.server"
  305. X#define PID_LIST      PATH/.pid.list"
  306. X#define CUT          "cut"
  307. X#define AWK               "awk" /* Do a 'which awk' for proper path */
  308. X#define UPTIME            "uptime"  /* 'which uptime' */
  309. X#define MAILER_DAEMON     "MAILER|MAILER-DAEMON|MAILER-DEAMON|MAILER-DEMON|\
  310. DAEMON|DEAMON|DEMON|POSTMASTER|POST-MASTER|UUCP|ROOT"
  311. X              /* Preserve upper case; put all possibilities above
  312. X                 separated by a '|'; all of the above entries will
  313. X                 be used to identify mailer daemon messages so
  314. X                 they can get special treatment */
  315. X#define UCB_MAIL      "/usr/ucb/mail" /* Path to UCB mail program. Remove
  316. X              it if UCB mail is not installed on your system,
  317. X              in which case no mail is sent to MANAGER by 'serverd'
  318. X              or when the programs receive various signals. */
  319. X
  320. X/*
  321. X  These #define's should not be altered.
  322. X*/
  323. X
  324. X#define MAX_COMMANDS      15
  325. X#define KEEP_MESSAGE_IDS  500
  326. X#define DEFAULT_SERVER_ADDRESS       "listserv"
  327. X#define DEFAULT_SERVER_CMDOPTIONS ""
  328. X#define DEFAULT_SERVER_COMMENT      "Boston University List Server"
  329. X#define DEFAULT_MANAGER          "server"
  330. X#define MAX_LINE      256
  331. X#define EOS          '\0'
  332. X#define RESET(var)      (var[0]) = EOS
  333. X#define BSD_PS          0x01
  334. X#define    SYSV_PS          0x02
  335. X#define    USE_TELNET      0x04
  336. X#define USE_ENV_VAR      0x08
  337. X#define USE_MY_SYSTEM      0x10
  338. X#define BSD_MAIL      0x20
  339. X#define POST_MAIL      0x40
  340. X#define GATE_MAIL      0x80
  341. X#define USE_SYSMAIL      0x100
  342. X#define LIMIT_MSG      0x200
  343. X#define START_OF_MESSAGE  "From " /* UNIX mail messages start w/ this string */
  344. X#define ACK          "ACK"   /* Send message back to sender */
  345. X#define NOACK          "NOACK" /* Do not send message back to sender */
  346. X#define POSTPONE      "POSTPONE"  /* Postpone sending mail */
  347. X#define MAX_SIGNAL      NSIG    /* Highest system signal caught */
  348. X#define BOOLEAN          unsigned short int
  349. X#define TRUE          1
  350. X#define FALSE          0
  351. X#define SUBSCRIBED      TRUE    /* Subscribed sender */
  352. X#define NOTSUBSCRIBED      FALSE   /* Sender is not subscribed */
  353. X#define NEWS          TRUE+1  /* News feed */
  354. X#define PEER          TRUE+2
  355. X#define NEW_ARRIVAL      "\n--- NEW MAIL HAS ARRIVED ---\n"
  356. X#define MAX_LISTS      10
  357. X#define SUBJECT          "Subject: "
  358. X#define MESSAGE_ID1       "Message-Id: "
  359. X#define MESSAGE_ID2      "Message-ID: "
  360. X#define MESSAGE_ID3      "Message-id: "
  361. X
  362. X#define COMPLETE_TELNET(f) \
  363. X if (sys.options & USE_TELNET) \
  364. X   COMPLETE_FILE (f)
  365. END_OF_FILE
  366. if test 4982 -ne `wc -c <'src/defs.h'`; then
  367.     echo shar: \"'src/defs.h'\" unpacked with wrong size!
  368. fi
  369. # end of 'src/defs.h'
  370. fi
  371. if test -f 'src/sender.c' -a "${1}" != "-c" ; then 
  372.   echo shar: Will not clobber existing file \"'src/sender.c'\"
  373. else
  374. echo shar: Extracting \"'src/sender.c'\" \(6930 characters\)
  375. sed "s/^X//" >'src/sender.c' <<'END_OF_FILE'
  376. X/*
  377. X  ----------------------------------------------------------------------------
  378. X  |                      SENDER ORIENTED FUNCTIONS                 |
  379. X  |                                                                          |
  380. X  |                              Version 2.0                                 |
  381. X  |                                                                          |
  382. X  |                (or, when Computer Science gets to you)                   |
  383. X  |                                                                          |
  384. X  |                    Written by Anastasios Kotsikonas                      |
  385. X  |                           (tasos@cs.bu.edu)                              |
  386. X  |                                                                          |
  387. X  | AGREEMENT: This software can be used and distributed freely as long      |
  388. X  | as you do not remove or alter the Copyright notice in the file defs.h;   |
  389. X  | this notice is #define'd in the symbol VERSION. Although you may alter   |
  390. X  | the code provided, you may not alter the functions create_header()       |
  391. X  | and create_multi_recipient_header() in list.c and listserv.c.            |
  392. X  | By using this software you are bound by this agreement.                  |
  393. X  | This software comes with no warranties and cannot be sold for profit.    |
  394. X  | The AGREEMENT and COPYRIGHT notices should be included in all source     |
  395. X  | files when distributing this software.                                   |
  396. X  | COPYRIGHT: Copyright (c) 1991, Anastasios C. Kotsikonas                  |
  397. X  ----------------------------------------------------------------------------
  398. X*/
  399. X
  400. X#include <stdio.h>
  401. X#include <string.h>
  402. X#include <ctype.h>
  403. X#include "defs.h"
  404. X
  405. extern  void report_progress (FILE *, char *, int);
  406. extern  char *upcase (char *);
  407. extern  void extract_subscriber (FILE *, char *);
  408. X
  409. BOOLEAN subscribed (FILE *, char *, char *, char *, char *, char *);
  410. BOOLEAN check_file (FILE *, char *, char *, BOOLEAN);
  411. BOOLEAN ignore_sender (FILE *, char *, FILE *);
  412. void    extract_sender (char *);
  413. void    extract_subscriber (FILE *f, char *subscriber);
  414. void    extract_origin (char *);
  415. X
  416. X/*
  417. X  Check if 'sender' is subscribed. Return SUBSCRIBED, NEWS PEER or
  418. X  NOTSUBSCRIBED. Comparisons are done in upper case.
  419. X*/
  420. X
  421. BOOLEAN subscribed (FILE *report, char *sender, char *subscribersf,
  422. X            char *newsf, char *peersf, char *aliasesf)
  423. X{
  424. X  if (subscribersf == NULL) /* call made by distribute () in listserv.c */
  425. X    return NOTSUBSCRIBED;
  426. X  if (check_file (report, sender, subscribersf, FALSE) ||
  427. X      check_file (report, sender, aliasesf, TRUE))
  428. X    return SUBSCRIBED;
  429. X  else if (newsf != NULL && (check_file (report, sender, newsf, FALSE) ||
  430. X                 check_file (report, sender, aliasesf, TRUE)))
  431. X    return NEWS;
  432. X  else if (peersf != NULL && (check_file (report, sender, peersf, FALSE) ||
  433. X                  check_file (report, sender, aliasesf, TRUE)))
  434. X    return PEER;
  435. X  return NOTSUBSCRIBED;
  436. X}
  437. X
  438. X/*
  439. X  Check the given file for subscription. If the file is an aliases file
  440. X  and the sender is listed in there, store his actual mailing address
  441. X  in 'sender'.
  442. X*/
  443. X
  444. BOOLEAN check_file (FILE *report, char *sender, char *file,
  445. X            BOOLEAN checking_aliases)
  446. X{
  447. X  char subscriber [MAX_LINE];
  448. X  char mode [MAX_LINE];
  449. X  char name [MAX_LINE];
  450. X  char error [MAX_LINE];
  451. X  FILE *f;
  452. X
  453. X  if ((f = fopen (file, "r")) == NULL)
  454. X    RESET (error),
  455. X    sprintf (error, "\ncheck_file(): Could not open %s", file),
  456. X    report_progress (report, error, TRUE),
  457. X    exit (1);
  458. X  upcase (sender);          /* Convert to upper case */
  459. X  while (!feof (f)) {  /* Check list of subscribers */
  460. X    subscriber[0] = mode[0] = RESET (name);
  461. X    extract_subscriber (f, subscriber);
  462. X    fscanf (f, "%s ", mode);
  463. X    if (!checking_aliases)
  464. X      fgets (name, MAX_LINE - 2, f);
  465. X    upcase (subscriber);
  466. X    if (!strcmp (sender, subscriber)) {
  467. X      fclose (f);
  468. X      if (checking_aliases)
  469. X    upcase (mode),
  470. X    strcpy (sender, mode);
  471. X      return SUBSCRIBED;
  472. X    }
  473. X  }
  474. X  fclose (f);
  475. X  return NOTSUBSCRIBED;
  476. X}
  477. X
  478. X/*
  479. X  Check if 'sender' appears in the IGNORED file.
  480. X*/
  481. X
  482. BOOLEAN ignore_sender (FILE *ignored, char *sender, FILE *report)
  483. X{
  484. X  char report_msg [MAX_LINE];
  485. X  char ignored_user [MAX_LINE];
  486. X  char line[MAX_LINE];
  487. X
  488. X  rewind (ignored);
  489. X  while (!feof (ignored)) { /* Check the IGNORED file first */
  490. X    line[0] = RESET (ignored_user);
  491. X    fgets (line, MAX_LINE - 2, ignored);
  492. X    sscanf (line, "%s", ignored_user);
  493. X    upcase (ignored_user);
  494. X    if (ignored_user[0] != EOS)
  495. X      if (!strcmp (ignored_user, sender)) {
  496. X        RESET (report_msg);
  497. X        sprintf (report_msg, "User %s and message ignored.\n", sender);
  498. X        report_progress (report, report_msg, FALSE);
  499. X        return TRUE;
  500. X      }
  501. X  }
  502. X  return FALSE;
  503. X}
  504. X
  505. X/*
  506. X  Extract the sender's email address. To do that, skip over the leading
  507. X  "From ". That's where the address starts. Then put an EOS character at
  508. X  the end of this address (a blank terminates this address string).
  509. X*/
  510. X
  511. void extract_sender (char *s)
  512. X{
  513. X  int nsquote = 0, ndquote = 0, nparen = 0, nangle = 0, nsquare = 0;
  514. X  BOOLEAN done = FALSE;
  515. X
  516. X  sprintf (s, "%s", s + strlen (START_OF_MESSAGE));
  517. X  while (*s && !done) { /* Look for end of address substring */
  518. X    (*s == '\"' ? (nsquote ? (nsquote = 0) : (nsquote = 1)) : 0);
  519. X    (*s == '\"' ? (ndquote ? (ndquote = 0) : (ndquote = 1)) : 0);
  520. X    (*s == '(' ? ++nparen : 0);
  521. X    (*s == ')' ? --nparen : 0);
  522. X    (*s == '<' ? ++nangle : 0);
  523. X    (*s == '>' ? --nangle : 0);
  524. X    (*s == '[' ? ++nsquare : 0);
  525. X    (*s == ']' ? --nsquare : 0);
  526. X    ((*s == ' ' || *s == '\t') ?
  527. X     ((nsquote || ndquote || nparen || nangle || nsquare) ? 
  528. X      0 : (done = TRUE)) : 0);
  529. X    ++s;
  530. X  }
  531. X  *(s - 1) = EOS;  /* 's' is now pointing to the sender's address */
  532. X}
  533. X
  534. X/*
  535. X  Extract the subscriber's address from the file.
  536. X*/
  537. X
  538. void extract_subscriber (FILE *f, char *subscriber)
  539. X{
  540. X  int nsquote = 0, ndquote = 0, nparen = 0, nangle = 0, nsquare = 0, i = 0;
  541. X  BOOLEAN done = FALSE;
  542. X  char c;
  543. X
  544. X  while (!feof (f) && !done) {
  545. X    c = fgetc (f);
  546. X    (c == '\"' ? (nsquote ? (nsquote = 0) : (nsquote = 1)) : 0);
  547. X    (c == '\"' ? (ndquote ? (ndquote = 0) : (ndquote = 1)) : 0);
  548. X    (c == '(' ? ++nparen : 0);
  549. X    (c == ')' ? --nparen : 0);
  550. X    (c == '<' ? ++nangle : 0);
  551. X    (c == '>' ? --nangle : 0);
  552. X    (c == '[' ? ++nsquare : 0);
  553. X    (c == ']' ? --nsquare : 0);
  554. X    ((c == ' ' || c == '\t') ? 
  555. X     ((nsquote || ndquote || nparen || nangle || nsquare) ? 
  556. X      0 : (done = TRUE)) : 0);
  557. X    subscriber [i++] = c;
  558. X  }
  559. X  if (i > 0)
  560. X    subscriber[i - 1] = EOS;
  561. X}
  562. X
  563. X/*
  564. X  Extract the originator of the message, i.e. the list that the original
  565. X  message first originated from.
  566. X*/
  567. X
  568. void extract_origin (char *s)
  569. X{
  570. X  char *p;
  571. X
  572. X  if (p = strchr (s, '<'))
  573. X    sprintf (s, "%s", p + 1); /* Remove '<' */
  574. X  if (p = strchr (s, '>'))
  575. X    *p = EOS;  /* Remove '>' */
  576. X  else {  /* Get to the end of the address */
  577. X    while (*s != EOS && !isspace (*s))
  578. X      ++s;
  579. X    *s = EOS;
  580. X  }
  581. X}
  582. END_OF_FILE
  583. if test 6930 -ne `wc -c <'src/sender.c'`; then
  584.     echo shar: \"'src/sender.c'\" unpacked with wrong size!
  585. fi
  586. # end of 'src/sender.c'
  587. fi
  588. if test -f 'src/serverd.c' -a "${1}" != "-c" ; then 
  589.   echo shar: Will not clobber existing file \"'src/serverd.c'\"
  590. else
  591. echo shar: Extracting \"'src/serverd.c'\" \(9491 characters\)
  592. sed "s/^X//" >'src/serverd.c' <<'END_OF_FILE'
  593. X/*
  594. X  ----------------------------------------------------------------------------
  595. X  |                       DISCUSSION LIST SYSTEM DAEMON                 |
  596. X  |                                                                          |
  597. X  |                              Version 3.0                                 |
  598. X  |                                                                          |
  599. X  |                (or, when Computer Science gets to you)                   |
  600. X  |                                                                          |
  601. X  |                    Written by Anastasios Kotsikonas                      |
  602. X  |                           (tasos@cs.bu.edu)                              |
  603. X  |                                                                          |
  604. X  | AGREEMENT: This software can be used and distributed freely as long      |
  605. X  | as you do not remove or alter the Copyright notice in the file defs.h;   |
  606. X  | this notice is #define'd in the symbol VERSION. Although you may alter   |
  607. X  | the code provided, you may not alter the functions create_header() in    |
  608. X  | list.c and listserv.c. By using this software you are bound by this      |
  609. X  | agreement.                                                               |
  610. X  | This software comes with no warranties and cannot be sold for profit.    |
  611. X  | The AGREEMENT and COPYRIGHT notices should be included in all source     |
  612. X  | files when distributing this software.                                   |
  613. X  | COPYRIGHT: Copyright (c) 1991, Anastasios C. Kotsikonas                  |
  614. X  ----------------------------------------------------------------------------
  615. X
  616. X  Spawn list or listserv upon arrival of new messages. Send mail to
  617. X  MANAGER if something went wrong (only if using UCB mail).
  618. X  serverd will not spawn if the current load average is above max_load
  619. X  and the -l flag is on, until it has delayed MAX_TRIES * 30 seconds.
  620. X  serverd communicates with listerv via exit status 6 and 7; this are
  621. X  the request to shutdwon/restart the system; on status 7, serverd spawns
  622. X  start and dies; if it cannot restart, it sends mail and commits suicide.
  623. X  serverd reports to REPORT_SERVERD.
  624. X
  625. X  COMMAND LINE OPTIONS:
  626. X    -1: Execute only once -- to be used with cron.
  627. X    -l: Enforce restrictions based on the current load average.
  628. X    -e: Echo reports to the screen.
  629. X
  630. X  EXIT CODES:
  631. X    0: OK
  632. X    1: Could not open file
  633. X    2: Could not lock file
  634. X    3: Command line option error
  635. X    4: Syntax error in file
  636. X    5: Could not spawn
  637. X    6: Shutdown request
  638. X    7: Restart request
  639. X    8: Received system signal
  640. X    9: Too many multiple recipients
  641. X   10: Could not connect to server
  642. X   11: Server broke connection
  643. X   12: Could not create socket
  644. X   13: No such host
  645. X   14: Could not connect to port
  646. X   15: Connection timed out
  647. X   16: Malloc failed
  648. X*/
  649. X
  650. X#include <stdio.h>
  651. X#include <unistd.h>
  652. X#include <sys/types.h>
  653. X#include <sys/stat.h>
  654. X#include <fcntl.h>
  655. X#include <signal.h>
  656. X#include "defs.h"
  657. X#include "serverd.h"
  658. X#include "struct.h"
  659. X#include "global.h"
  660. X
  661. X#ifdef __STDC__
  662. X#include <stdarg.h>
  663. extern int  syscom (char *, ...);
  664. X#else
  665. X#include <varargs.h>
  666. extern int  syscom ();
  667. X#endif
  668. extern double atof ();
  669. extern int  sys_config (FILE *, SYS *);
  670. extern int  getopt (int, char **, char *);
  671. extern void init_signals (void);
  672. extern void catch_signals (void);
  673. X
  674. void   main (int, char **, char **);
  675. void   serverd_config (char *alias);
  676. void   usage (void);
  677. void   gexit (void);
  678. X
  679. char *exit_string[] = {  /* Define exit status strings */
  680. X/* 0 */ "OK", 
  681. X/* 1 */ "Could not open file", 
  682. X/* 2 */ "Could not lock file",
  683. X/* 3 */ "Command line option error",
  684. X/* 4 */ "Syntax error in file",
  685. X/* 5 */ "Could not spawn",
  686. X/* 6 */ "Shutdown request",
  687. X/* 7 */ "Restart request",
  688. X/* 8 */ "Received system signal",
  689. X/* 9 */ "Too many multiple recipients",
  690. X/* 10 */"Could not connect to server",
  691. X/* 11 */"Server broke connection",
  692. X/* 12 */"Could not create socket",
  693. X/* 13 */"No such host",
  694. X/* 14 */"Could not connect to port",
  695. X/* 15 */"Could not deliver mail",
  696. X/* 16 */"Malloc failed",
  697. X/* 17 */ "Unknown exit code"
  698. X};
  699. X  
  700. void main (int argc, char **argv, char **envp)
  701. X{
  702. X  struct stat stat_buf;
  703. X  int i, status, try, fd, nlists;
  704. X  FILE *f, *loadf, *report;
  705. X  float load, max_load;
  706. X  BOOLEAN loadr = FALSE, execute_once = FALSE;
  707. X  char list [MAX_LINE];
  708. X  char server [MAX_LINE];
  709. X  char msg [MAX_LINE];
  710. X  int c;
  711. X  char *options = "1l:e";
  712. X  extern char *optarg;
  713. X  extern int optopt;
  714. X
  715. X  while ((c = getopt (argc, argv, options)) != EOF)
  716. X    switch ((char) c) {
  717. X      case '1': execute_once = TRUE; break;
  718. X      case 'e': tty_echo = TRUE; break;
  719. X      case 'l': loadr = TRUE; 
  720. X        max_load = (float) atof (optarg); 
  721. X        break;
  722. X      case ':': 
  723. X        fprintf (stderr, "serverd:  Option '%c' requires an argument.\n",
  724. X         optopt);
  725. X    exit (3);
  726. X      case '?':
  727. X      default:
  728. X    usage ();
  729. X    }
  730. X#ifndef _MINIX
  731. X  if (lockf ((fd = open (SERVERD_LOCK_FILE, O_RDWR)), F_TLOCK, 0))
  732. X    fprintf (stderr, "serverd: Unable to lock %s. Aborting.\n", 
  733. X             SERVERD_LOCK_FILE),
  734. X    exit (2);
  735. X#endif
  736. X  if ((report = fopen (REPORT_SERVERD, "a")) == NULL)
  737. X    fprintf (stderr, "serverd: Could not open %s\n", REPORT_SERVERD),
  738. X    exit (1);
  739. X
  740. X  if ((f = fopen (PID_SERVERD, "w")) != NULL)
  741. X    fprintf (f, "%d", getpid()),
  742. X    fclose (f);
  743. X  signal (SIGINT, gexit);
  744. X  init_signals();
  745. X  catch_signals ();
  746. X
  747. X  nlists = sys_config (report, &sys);
  748. X  while (007) {
  749. X    for (i = 0; i < nlists; ++i) {
  750. X      serverd_config (sys.lists[i].alias);
  751. X      if (!stat (list_mail_f, &stat_buf) && stat_buf.st_size > 0) {
  752. X    sprintf (msg, "\n--- NEW MAIL FOR %s ---\n", sys.lists[i].alias);
  753. X    report_progress (report, msg, FALSE);
  754. X        if (loadr) { /* enforce restrictions */
  755. X          try = 0;
  756. X        again_list:
  757. X          syscom ("%s | %s -F, '{ print $4 }' | %s -d' ' -f5 > %s",
  758. X          UPTIME, AWK, CUT, LOAD_FILE);
  759. X          if ((loadf = fopen (LOAD_FILE, "r")) == NULL)
  760. X        sprintf (msg, "\nCould not open %s", LOAD_FILE),
  761. X        report_progress (report, msg, TRUE),
  762. X        exit (1);
  763. X          fscanf (loadf, "%f", &load);
  764. X          fclose (loadf);
  765. X          unlink (LOAD_FILE);
  766. X          if (load > max_load && try < MAX_TRIES) {
  767. X        ++try;
  768. X            sleep (30);
  769. X        goto again_list;
  770. X          }
  771. X        }
  772. X    RESET (list);
  773. X    sprintf (list, "%s %s %s", LIST, sys.lists[i].alias,
  774. X         sys.lists[i].cmdoptions);
  775. X    report_progress (report, list, TRUE);
  776. X        if ((status = system (list)) > 127) {   /* run list */
  777. X          sprintf (msg, "serverd died: LIST: %s", exit_string[status / 256]);
  778. X          if (sys.options & BSD_MAIL)
  779. X        syscom ("%s -s \"%s\" %s < /dev/null", UCB_MAIL, msg, sys.manager);
  780. X      report_progress (report, msg, TRUE);
  781. X      exit (status / 256);
  782. X        }
  783. X        else if (status == 127) {
  784. X      sprintf (msg, "serverd died: could not execute shell for list");
  785. X      if (sys.options & BSD_MAIL)
  786. X        syscom ("%s -s \"%s\" %s < /dev/null", UCB_MAIL, msg, sys.manager);
  787. X      report_progress (report, msg, TRUE);
  788. X      exit (5);
  789. X        }
  790. X      }
  791. X      if (sys.frequency > 0)
  792. X        sleep (sys.frequency);     /* do a quickie to The Spy Who Loved Him */
  793. X    }
  794. X    if (!stat (SERVER_MAIL_FILE, &stat_buf) && stat_buf.st_size > 0) {
  795. X      report_progress (report, "\n--- NEW MAIL FOR SERVER ---\n", FALSE);
  796. X      if (loadr) { /* Enforce restrictions */
  797. X        try = 0;
  798. X      again_server:
  799. X        syscom ("%s | %s -F, '{ print $4 }' | %s -d' ' -f5 > %s",
  800. X                UPTIME, AWK, CUT, LOAD_FILE);
  801. X        if ((loadf = fopen (LOAD_FILE, "r")) == NULL)
  802. X          sprintf (msg, "\nCould not open %s", LOAD_FILE),
  803. X          report_progress (report, msg, TRUE),
  804. X          exit (1);
  805. X        fscanf (loadf, "%f", &load);
  806. X        fclose (loadf);
  807. X        unlink (LOAD_FILE);
  808. X        if (load > max_load && try < MAX_TRIES) {
  809. X          ++try;
  810. X          sleep (30);
  811. X          goto again_server;
  812. X        }
  813. X      }
  814. X      RESET (server);
  815. X      sprintf (server, "%s %s", SERVER, sys.server.cmdoptions);
  816. X      report_progress (report, server, TRUE);
  817. X      if ((status = system (server)) > 127) { /* run server */
  818. X        sprintf (msg,"serverd died: LISTSERV: %s", exit_string[status / 256]);
  819. X    if (sys.options & BSD_MAIL)
  820. X      syscom ("%s -s \"%s\" %s < /dev/null", UCB_MAIL, msg, sys.manager);
  821. X    report_progress (report, msg, TRUE);
  822. X    if (status == 6 * 256)  /* Shutdown request */
  823. X      unlink (PID_SERVERD),
  824. X      exit (6);
  825. X    if (status == 7 * 256) {  /* Restart request */
  826. X      execl (START, START_OPTIONS, START_OPTIONS, NULL);
  827. X      sprintf (msg, "serverd commits suicide: Could not restart system");
  828. X          report_progress (report, msg, TRUE);
  829. X          if (sys.options & BSD_MAIL)
  830. X            syscom ("%s -s \"%s\" %s < /dev/null", UCB_MAIL, msg, sys.manager);
  831. X      exit (5);
  832. X    }
  833. X    else
  834. X      exit (status / 256);
  835. X      }
  836. X      else if (status == 127) {
  837. X    sprintf (msg, "serverd died: could not execute shell for listserv");
  838. X    if (sys.options & BSD_MAIL)
  839. X      syscom ("%s -s \"%s\" %s < /dev/null", UCB_MAIL, msg, sys.manager);
  840. X    report_progress (report, msg, TRUE);
  841. X    exit (5);
  842. X      }
  843. X    }
  844. X    if (execute_once)
  845. X      gexit();
  846. X    if (sys.frequency > 0)
  847. X      sleep (sys.frequency);     /* do a quickie to Money Penny */
  848. X  }
  849. X}
  850. X
  851. void serverd_config (char *alias)
  852. X{
  853. X  setup_string (list_mail_f, alias, LIST_MAIL_FILE);
  854. X}
  855. X
  856. void usage ()
  857. X{
  858. X  fprintf (stderr, "Usage: serverd [-1] [-e] [-l load]\n\
  859. X-1: Execute only once.\n\
  860. X-e: Echo reports to the screen.\n\
  861. X-l: Enforce load restrictions.\n");
  862. X  exit (3);
  863. X}
  864. X
  865. X/*
  866. X  Graceful exit. Remove pid file.
  867. X*/
  868. X
  869. void gexit ()
  870. X{
  871. X  unlink (PID_SERVERD);
  872. X  exit (0);
  873. X}
  874. END_OF_FILE
  875. if test 9491 -ne `wc -c <'src/serverd.c'`; then
  876.     echo shar: \"'src/serverd.c'\" unpacked with wrong size!
  877. fi
  878. # end of 'src/serverd.c'
  879. fi
  880. if test -f 'src/start.c' -a "${1}" != "-c" ; then 
  881.   echo shar: Will not clobber existing file \"'src/start.c'\"
  882. else
  883. echo shar: Extracting \"'src/start.c'\" \(12157 characters\)
  884. sed "s/^X//" >'src/start.c' <<'END_OF_FILE'
  885. X/*
  886. X  ----------------------------------------------------------------------------
  887. X  |                  DISCUSSION LIST SYSTEM HOUSEKEEPER                      |
  888. X  |                                                                          |
  889. X  |                              Version 2.5                                 |
  890. X  |                                                                          |
  891. X  |                (or, when Computer Science gets to you)                   |
  892. X  |                                                                          |
  893. X  |                    Written by Anastasios Kotsikonas                      |
  894. X  |                           (tasos@cs.bu.edu)                              |
  895. X  |                                                                          |
  896. X  | AGREEMENT: This software can be used and distributed freely as long         |
  897. X  | as you do not remove or alter the Copyright notice in the file defs.h;   |
  898. X  | this notice is #define'd in the symbol VERSION. Although you may alter   |
  899. X  | the code provided, you may not alter the functions create_header()       |
  900. X  | and create_multi_recipient_header() in list.c and listserv.c.            |
  901. X  | By using this software you are bound by this agreement.                  |
  902. X  | This software comes with no warranties and cannot be sold for profit.    |
  903. X  | The AGREEMENT and COPYRIGHT notices should be included in all source     |
  904. X  | files when distributing this software.                                   |
  905. X  | COPYRIGHT: Copyright (c) 1991, Anastasios C. Kotsikonas             |
  906. X  ----------------------------------------------------------------------------
  907. X
  908. X  This is the proper way of starting the discussion list. The program verifies
  909. X  that no other serverd, list or listserv programs are running on the 
  910. X  system (and kills them before proceeding -- after confirming), 
  911. X  makes sure the required files exist (and creates new ones if missing -- 
  912. X  after confirming), backs up all reports into files with extension .acc,
  913. X  creates new directories for new discussion lists as necessary,
  914. X  and finally spawns serverd. start reports to REPORT_START.
  915. X
  916. X  COMMAND LINE OPTIONS:
  917. X    -k: just kill all pertinent programs that may already be running; no
  918. X    discussion list is started in this case.
  919. X    -c: Do not confirm before killing a process.
  920. X    -r: Do not report; useful when starting up when system is rebooted.
  921. X  
  922. X  WARNING: The program won't work correctly in the absence of an extended
  923. X  egrep facility that does matching at the end of a line with a $ and 
  924. X  accepts multiple regular expressions separated by a |. In this case,
  925. X  the user may have to manually look for and terminate any such programs.
  926. X  Also when the output of the 'ps' command exceeds 80 characters (due perhaps
  927. X  to long path names) the user may again have to terminate programs by hand.
  928. X  Note that a file locking mechanism  for serverd, list and listserv is used 
  929. X  to ensure against multiple executions of the same program.
  930. X
  931. X  WARNING: When using the SYSV ps command and it chops output to 80 characters,
  932. X  start may not be able to locate processes already running; this may occur if
  933. X  the path to /usr/server is too long.
  934. X*/
  935. X
  936. X#include <stdio.h>
  937. X#include <signal.h>
  938. X#include <sys/types.h>
  939. X#include <sys/stat.h>
  940. X#include "defs.h"
  941. X#include "start.h"
  942. X#include "struct.h"
  943. X#include "global.h"
  944. X
  945. X#define GET_RESPONSE  {\
  946. X            fflush (stdout); \
  947. X            fflush (stdin); \
  948. X            c = fgetc (stdin); \
  949. X            if (c != '\n' && c != EOF) \
  950. X              while (fgetc (stdin) != '\n'); \
  951. X            fflush (stdin);\
  952. X              }
  953. X
  954. X/*
  955. X  Function prototypes:
  956. X*/
  957. X
  958. X#ifdef __STDC__
  959. X#include <stdarg.h>
  960. extern int  syscom (char *, ...);
  961. X#else
  962. X#include <varargs.h>
  963. extern int  syscom ();
  964. X#endif
  965. extern char *extract_filename (char *);
  966. extern void report_progress (FILE *, char *, int);
  967. extern int  getopt (int, char **, char *);
  968. void   main (int, char **);
  969. void   check_for (char *, FILE *, BOOLEAN, BOOLEAN);
  970. void   usage (void);
  971. void   start_abort (void);
  972. void   backup (char *, char *);
  973. void   start_config (char *);
  974. X
  975. void main (int argc, char **argv)
  976. X{
  977. X  char command [256];
  978. X  char line [MAX_LINE];
  979. X  char msg [2 * MAX_LINE];
  980. X  char dir [MAX_LINE];
  981. X  char *addr1, *addr2, *addr3, *addr4, *options = "ckr";
  982. X  int c;
  983. X  FILE *f, *p, *report;
  984. X  int i, nlists, pid, procs_killed = 0, procs;
  985. X  BOOLEAN just_kill = FALSE, confirm = TRUE, do_report = TRUE;
  986. X  struct stat stat_buf;
  987. X  extern char *optarg;
  988. X  extern int optopt;
  989. X  
  990. X  while ((c = getopt (argc, argv, options)) != EOF)
  991. X    switch ((char) c) {
  992. X      case 'c': confirm = FALSE; break;
  993. X      case 'k': just_kill = TRUE; break;
  994. X      case 'r': do_report = FALSE; break;
  995. X      case '?':
  996. X      default:
  997. X    usage();
  998. X    }
  999. X
  1000. X  /* First make sure no other SERVERD programs are running. If so, kill
  1001. X     them all (after confirming) before proceeding. */
  1002. X  
  1003. X  backup (REPORT_START, REPORT_START_ACC);
  1004. X  if ((report = fopen (REPORT_START, "a")) == NULL)
  1005. X    fprintf (stderr, "start: Could not open %s\n", REPORT_START),
  1006. X    start_abort();
  1007. X  nlists = sys_config (report, &sys);
  1008. X  if (just_kill)
  1009. X    report_progress (report, "\n--- SHUTTING LISTSERV SYSTEM DOWN ---\n",FALSE);
  1010. X  else
  1011. X    report_progress (report, "\n--- STARTING LISTSERV SYSTEM ---\n", FALSE);
  1012. X#ifndef _MINIX
  1013. X  if (sys.options & BSD_PS)
  1014. X    syscom ("ps -gx > /tmp/ps");  /* do not combine the two "syscom"'s */
  1015. X  else
  1016. X    syscom ("ps -ef | grep %s > /tmp/ps", getenv ("LOGNAME"));
  1017. X  tty_echo = FALSE;
  1018. X  syscom ("egrep '%s$|%s|%s$|%s |%s$|%s |%s|%s |queued' /tmp/ps > /tmp/found",
  1019. X      (addr1 = extract_filename (SERVERD)), addr1,
  1020. X       (addr2 = extract_filename (LIST)), addr2,
  1021. X      (addr3 = extract_filename (SERVER)), addr3,
  1022. X      (addr4 = extract_filename (PQUEUE)), addr4);
  1023. X  free ((char *) addr1);
  1024. X  free ((char *) addr2);
  1025. X  free ((char *) addr3);
  1026. X  free ((char *) addr4);
  1027. X  unlink ("/tmp/ps");
  1028. X  tty_echo = TRUE;
  1029. X  if ((f = fopen ("/tmp/found", "r")) == NULL)
  1030. X    sprintf (msg, "Error opening /tmp/found. Aborting. %s",
  1031. X         ((just_kill == FALSE) ? "No discussion list started." : "")),
  1032. X    report_progress (report, msg, TRUE),
  1033. X    start_abort ();
  1034. X  
  1035. X  syscom ("wc -l /tmp/found > /tmp/nprocs");
  1036. X  if ((p = fopen ("/tmp/nprocs", "r")) != NULL) {
  1037. X    fscanf (p, "%d", &procs);
  1038. X    if (do_report)
  1039. X      sprintf (msg, "OLD LISTSERV PROCESSES RUNNING:\t%d\n", procs),
  1040. X      report_progress (report, msg, FALSE);
  1041. X    fclose (p);
  1042. X    unlink ("/tmp/nprocs");
  1043. X  }
  1044. X  else
  1045. X    sprintf (msg, "Error opening /tmp/nprocs. Aborting. %s",
  1046. X         ((just_kill == FALSE) ? "No discussion list started." : "")),
  1047. X    report_progress (report, msg, TRUE),
  1048. X    start_abort ();
  1049. X  
  1050. X  while (!feof (f)) {  /* get pid's and kill processes after confirming */
  1051. X    RESET (line);
  1052. X    fgets (line, MAX_LINE - 2, f);
  1053. X    if (line[0] != EOS) {
  1054. X      if (sys.options & BSD_PS)
  1055. X        sscanf (line, "%d ", &pid);
  1056. X      else
  1057. X        sscanf (line, "%s %d ", command, &pid);
  1058. X      if (confirm) {
  1059. X    c = EOS;
  1060. X        while (c != EOF && c != 'Y' && c != 'N') {
  1061. X      sprintf (msg, "\n%s\n%c[7m%s%c[mKill it to proceed ? (Y/N) ",
  1062. X           ((just_kill == FALSE) ? 
  1063. X            "ERROR: another listserv-system program running:" : 
  1064. X            "Listserv-system program found:"),
  1065. X           27, line, 27);
  1066. X      report_progress (report, msg, FALSE);
  1067. X      GET_RESPONSE;
  1068. X        }
  1069. X        if (c == 'N' || c == EOF)
  1070. X      sprintf (msg, "start aborted. %s\n",
  1071. X           ((just_kill == FALSE) ? "System not started.":"")),
  1072. X      report_progress (report, msg, TRUE),
  1073. X      exit (1);
  1074. X      }
  1075. X      kill (pid, SIGINT);
  1076. X      ++procs_killed;
  1077. X    }
  1078. X  }
  1079. X  fclose (f);
  1080. X  unlink ("/tmp/found");
  1081. X  if ((f = fopen (PID_SERVERD, "r")) != NULL)
  1082. X    fscanf (f, "%d", &pid),
  1083. X    kill (pid, SIGINT),
  1084. X    ++procs_killed,
  1085. X    fclose (f),
  1086. X    unlink (PID_SERVERD);
  1087. X  if ((f = fopen (PID_LIST, "r")) != NULL)
  1088. X    fscanf (f, "%d", &pid),
  1089. X    kill (pid, SIGINT),
  1090. X    ++procs_killed,
  1091. X    fclose (f),
  1092. X    unlink (PID_LIST);
  1093. X  if ((f = fopen (PID_SERVER, "r")) != NULL)
  1094. X    fscanf (f, "%d", &pid),
  1095. X    kill (pid, SIGINT),
  1096. X    ++procs_killed,
  1097. X    fclose (f),
  1098. X    unlink (PID_SERVER);
  1099. X  if ((f = fopen (PID_PQUEUE, "r")) != NULL)
  1100. X    fscanf (f, "%d", &pid),
  1101. X    kill (pid, SIGINT),
  1102. X    ++procs_killed,
  1103. X    fclose (f),
  1104. X    unlink (PID_PQUEUE);
  1105. X  if (do_report)
  1106. X    sprintf (msg, "OLD LISTSERV PROCESSES KILLED:\t%d\n", procs_killed),
  1107. X    report_progress (report, msg, FALSE);
  1108. X  
  1109. X  if (just_kill)  /* Done */
  1110. X    report_progress (report, "", -TRUE),
  1111. X    fclose (report),
  1112. X    exit (0);
  1113. X#endif
  1114. X  
  1115. X  syscom ("echo Serverd lock file > %s", SERVERD_LOCK_FILE);
  1116. X  syscom ("echo List lock file > %s", LIST_LOCK_FILE);
  1117. X  syscom ("echo Server lock file > %s", SERVER_LOCK_FILE);
  1118. X  syscom ("echo Pqueue lock file > %s", PQUEUE_LOCK_FILE);
  1119. X
  1120. X  backup (REPORT_SERVER, REPORT_SERVER_ACC);
  1121. X  backup (REPORT_SERVERD, REPORT_SERVERD_ACC);
  1122. X  backup (REPORT_PQUEUE, REPORT_PQUEUE_ACC);
  1123. X  sprintf (server_ignoredf, "%s/%s", PATH", IGNORED);
  1124. X  check_for (server_ignoredf, report, do_report, confirm);
  1125. X  for (i = 0; i < nlists; ++i) {
  1126. X    start_config (sys.lists[i].alias);
  1127. X    sprintf (dir, "%s/lists/%s", PATH", sys.lists[i].alias);
  1128. X    if (stat (dir, &stat_buf)) {
  1129. X      if (mkdir (dir, 475))
  1130. X    sprintf (msg, "Could not create directory %s", dir),
  1131. X    report_progress (report, msg, TRUE),
  1132. X    start_abort ();
  1133. X      syscom ("chmod 733 %s", dir);
  1134. X      if (do_report)
  1135. X        sprintf (msg, "*** New list %s ***\n", sys.lists[i].alias),
  1136. X        report_progress (report, msg, FALSE);
  1137. X      syscom ("cp %s %s", server_ignoredf, dir);
  1138. X      syscom ("echo %s >> %s/%s", sys.lists[i].alias, dir, IGNORED);
  1139. X      syscom ("echo %s >> %s/%s", sys.lists[i].address, dir, IGNORED);
  1140. X      syscom ("echo %s | sed 's/listserv/server/' >> %s/%s", sys.server.address,
  1141. X          dir, IGNORED);
  1142. X      syscom ("touch %s", infof);
  1143. X      syscom ("touch %s", welcomef);
  1144. X      syscom ("touch %s/%s", dir, LIST_MAIL_FILE);
  1145. X      syscom ("chmod 666 %s/%s", dir, LIST_MAIL_FILE);
  1146. X      syscom ("touch %s/%s", dir, MODERATED_MAIL_FILE);
  1147. X      syscom ("chmod 666 %s/%s", dir, MODERATED_MAIL_FILE);
  1148. X    }
  1149. X    check_for (subscribersf, report, do_report, confirm);
  1150. X    check_for (aliasesf, report, do_report, confirm);
  1151. X    check_for (newsf, report, do_report, confirm);
  1152. X    check_for (peersf, report, do_report, confirm);
  1153. X    check_for (restrictedf, report, do_report, confirm);
  1154. X    backup (report_listf, report_list_accf);
  1155. X  }
  1156. X  syscom ("%s %s &", SERVERD, sys.serverd_cmdoptions);
  1157. X  report_progress (report, "", -TRUE);
  1158. X  fclose (report);
  1159. X  exit (0);
  1160. X}
  1161. X
  1162. X/*
  1163. X  Make sure that file 's' exists. Create a new one if necessary.
  1164. X*/
  1165. X
  1166. void check_for (char *s, FILE *report, BOOLEAN do_report, BOOLEAN confirm)
  1167. X{
  1168. X  char c = EOS, msg [MAX_LINE];
  1169. X  struct stat stat_buf;
  1170. X
  1171. X  if (stat (s, &stat_buf)) { /* make sure we have file 's' */
  1172. X    if (confirm) {
  1173. X      while (c != EOF && c != 'Y' && c != 'N') {
  1174. X     if (do_report)
  1175. X          sprintf (msg, "No %s file found. Create a new one? (Y/N) ", s),
  1176. X      report_progress (report, msg, FALSE);
  1177. X        GET_RESPONSE;
  1178. X      }
  1179. X      if (c == 'N' || c == EOF)
  1180. X        start_abort ();
  1181. X    }
  1182. X    syscom ("touch %s", s);
  1183. X  }
  1184. X}
  1185. X
  1186. X/*
  1187. X  Append 'src' to 'dest' and create a brand new 'src'.
  1188. X*/
  1189. X
  1190. void backup (char *src, char *dest)
  1191. X{
  1192. X  struct stat stat_buf;
  1193. X
  1194. X  if (!stat (src, &stat_buf)) /* prepare for backup */
  1195. X    syscom ("cat %s >> %s", src, dest),
  1196. X    unlink (src),
  1197. X    syscom ("touch %s", src);
  1198. X}
  1199. X
  1200. X/*
  1201. X  Print usage.
  1202. X*/
  1203. X
  1204. void usage ()
  1205. X{
  1206. X  fprintf (stderr, "Usage: start [-k] [-c] [-r]\n\
  1207. X-k: Just kill any listserv-system programs running.\n\
  1208. X-c: Do not confirm before killing processes.\n\
  1209. X-r: Restrict reporting to screen.\n");
  1210. X  exit (1);
  1211. X}
  1212. X
  1213. X/*
  1214. X  Abort after printing a message.
  1215. X*/
  1216. X
  1217. void start_abort ()
  1218. X{
  1219. X  fprintf (stderr, "### start aborted; discussion list not started. ###\n");
  1220. X  exit (1);
  1221. X}
  1222. X
  1223. void start_config (char *alias)
  1224. X{
  1225. X  setup_string (subscribersf, alias, SUBSCRIBERS);
  1226. X  setup_string (aliasesf, alias, ALIASES);
  1227. X  setup_string (newsf, alias, NEWSF);
  1228. X  setup_string (peersf, alias, PEERS);
  1229. X  setup_string (restrictedf, alias, RESTRICTED);
  1230. X  setup_string (ignoredf, alias, IGNORED);
  1231. X  setup_string (report_listf, alias, REPORT_LIST);
  1232. X  setup_string (infof, alias, INFO_FILE);
  1233. X  setup_string (welcomef, alias, WELCOME_FILE);
  1234. X  setup_string (report_list_accf, alias, REPORT_LIST_ACC);
  1235. X}
  1236. END_OF_FILE
  1237. if test 12157 -ne `wc -c <'src/start.c'`; then
  1238.     echo shar: \"'src/start.c'\" unpacked with wrong size!
  1239. fi
  1240. # end of 'src/start.c'
  1241. fi
  1242. if test -f 'src/sysmail.c' -a "${1}" != "-c" ; then 
  1243.   echo shar: Will not clobber existing file \"'src/sysmail.c'\"
  1244. else
  1245. echo shar: Extracting \"'src/sysmail.c'\" \(6501 characters\)
  1246. sed "s/^X//" >'src/sysmail.c' <<'END_OF_FILE'
  1247. X/*
  1248. X  ----------------------------------------------------------------------------
  1249. X  |                       SYSTEM MAILING ROUTINES                            |
  1250. X  |                                         |
  1251. X  |                             Version 1.0                                  |
  1252. X  |                                                                          |
  1253. X  |                (or, when Computer Science gets to you)                   |
  1254. X  |                                                                          |
  1255. X  |                    Written by Anastasios Kotsikonas                      |
  1256. X  |                           (tasos@cs.bu.edu)                              |
  1257. X  |                                                                          |
  1258. X  | AGREEMENT: This software can be used and distributed freely as long      |
  1259. X  | as you do not remove or alter the Copyright notice in the file defs.h;   |
  1260. X  | this notice is #define'd in the symbol VERSION. Although you may alter   |
  1261. X  | the code provided, you may not alter the functions create_header()       |
  1262. X  | and create_multi_recipient_header() in list.c and listserv.c.            |
  1263. X  | By using this software you are bound by this agreement.                  |
  1264. X  | This software comes with no warranties and cannot be sold for profit.    |
  1265. X  | The AGREEMENT and COPYRIGHT notices should be included in all source     |
  1266. X  | files when distributing this software.                                   |
  1267. X  | COPYRIGHT: Copyright (c) 1991, Anastasios C. Kotsikonas                  |
  1268. X  ----------------------------------------------------------------------------
  1269. X
  1270. X  These routines implement the 'system' mailmethod. The system opens a socket
  1271. X  and connects directly with sendmail for mail delivery. During the process
  1272. X  of porting the code to various platforms, lots of grosse things were
  1273. X  encountered with sockets and protocols, so the code may seem kludgy.
  1274. X
  1275. X  When mail cannot be sent due to network problems, it is queued up and will 
  1276. X  be delivered later by the queue daemon.
  1277. X*/
  1278. X
  1279. X#include <stdio.h>
  1280. X#include <string.h>
  1281. X#include <sys/types.h>
  1282. X#include <sys/socket.h>
  1283. X#include <netinet/in.h>
  1284. X#include <netdb.h>
  1285. X#include "defs.h"
  1286. X#include "struct.h"
  1287. X#include "sysmail.h"
  1288. X
  1289. X#ifdef __STDC__
  1290. X#include <stdarg.h>
  1291. extern int  syscom (char *, ...);
  1292. X#else
  1293. X#include <varargs.h>
  1294. extern int  syscom ();
  1295. X#endif
  1296. extern FILE *report;
  1297. extern SYS sys;
  1298. extern BOOLEAN debug;
  1299. X
  1300. extern void report_progress (FILE *, char *, int);
  1301. X
  1302. BOOLEAN sysmail (char *);
  1303. BOOLEAN _sysmail (char *, int);
  1304. int     server_response (int, FILE *);
  1305. int     build_tcp_connection (FILE *);
  1306. void    queue_up (char *file);
  1307. X
  1308. X/*
  1309. X  The return value depends on the return value of _sysmail ().
  1310. X*/
  1311. X
  1312. BOOLEAN sysmail (char *file)
  1313. X{
  1314. X  char error [MAX_LINE];
  1315. X
  1316. X  queue = FALSE;
  1317. X  if (debug) {
  1318. X    if ((sent = fopen (SENT, "w")) == NULL)
  1319. X      sprintf (error, "\nsysmail(): Could not open %s", SENT),
  1320. X      report_progress (report, error, TRUE),
  1321. X      exit (1);
  1322. X    if ((received = fopen (RECEIVED, "w")) == NULL)
  1323. X      sprintf (error, "\nsysmail(): Could not open %s", RECEIVED),
  1324. X      report_progress (report, error, TRUE),
  1325. X      exit (1);
  1326. X  }
  1327. X  return _sysmail (file, 1);
  1328. X}
  1329. X
  1330. X/*
  1331. X  'system' mailmethod. It returns TRUE if the mail was successfully
  1332. X  delivered, FALSE if it was queued.
  1333. X*/
  1334. X
  1335. BOOLEAN _sysmail (char *file, int call)
  1336. X{
  1337. X  char buf [MAX_LINE] ;
  1338. X  char error [MAX_LINE];
  1339. X  FILE *msg;
  1340. X  int sock_fd, cmd, timeout;
  1341. X   
  1342. X  if ((msg = fopen (file, "r")) == NULL)
  1343. X    sprintf (error, "\n_sysmail(): Could not open %s", file),
  1344. X    report_progress (report, error, TRUE),
  1345. X    exit (1);
  1346. X  sock_fd = build_tcp_connection (report);
  1347. X  if ((cmd = server_response (sock_fd, report)) != ACKNOWLEDGE) {
  1348. X    report_progress (report, "\n_sysmail(): Could not connect to server", TRUE);
  1349. X    queue = TRUE;
  1350. X    goto abort;
  1351. X  }
  1352. X
  1353. X  PROTOCOL (DATA);
  1354. X  while (!feof (msg) && strcmp (buf, END_OF_TEXT)) { /* Copy header and text */
  1355. X    RESET (buf);
  1356. X    fgets (buf, MAX_LINE - 2, msg);
  1357. X    write (sock_fd, buf, strlen (buf));
  1358. X    if (debug)
  1359. X      fprintf (sent, "%s", buf),
  1360. X      fflush (sent);
  1361. X  }
  1362. X  cmd = server_response (sock_fd, report);
  1363. X  PROTOCOL (CLOSE_CONNECTION);
  1364. X  abort:
  1365. X  if (queue)
  1366. X    queue_up (file);
  1367. X  CLOSEF;
  1368. X  if (debug)
  1369. X    fclose (sent),
  1370. X    fclose (received);
  1371. X  if (queue)
  1372. X    return FALSE;
  1373. X  else
  1374. X    return TRUE;
  1375. X}
  1376. X
  1377. X/*
  1378. X  Get server response. Return the command number that the server sent.
  1379. X*/
  1380. X
  1381. int server_response (int sock_fd, FILE *report)
  1382. X{
  1383. X  char buf [MAX_LINE];
  1384. X  int cmd, i;
  1385. X
  1386. X  if (read (sock_fd, buf, 3) < 0) /* Get server command */
  1387. X    report_progress (report, "\nserver_response(): Server dropped connection",
  1388. X             TRUE),
  1389. X    exit (11);
  1390. X  RESET (message);
  1391. X  buf[3] = EOS;
  1392. X  cmd = atoi (buf);
  1393. X  sprintf (message, "%s", buf);
  1394. X  i = strlen (message);
  1395. X  if (debug)
  1396. X    fprintf (received, "%s", buf),
  1397. X    fflush (received);
  1398. X  while (buf[0] != '\n') { /* Read till the end of socket */
  1399. X    if (read (sock_fd, buf, 1) < 1) {
  1400. X      if (debug)
  1401. X        fprintf (received, "%s", buf),
  1402. X     fflush (received);
  1403. X      message [i] = EOS;
  1404. X      break;
  1405. X    }
  1406. X    message [i++] = (buf[0] != '\n' ? buf[0] : EOS);
  1407. X    if (debug)
  1408. X      fprintf (received, "%c", buf[0]),
  1409. X      fflush (received);
  1410. X  }
  1411. X  return cmd;
  1412. X}
  1413. X
  1414. X/*
  1415. X  Establish connection with sendmail/smtp.
  1416. X*/
  1417. X
  1418. int build_tcp_connection (FILE *report)
  1419. X{
  1420. X  int sock_fd;
  1421. X  struct sockaddr_in sin;
  1422. X  struct hostent *hostentry;
  1423. X   
  1424. X  if ((sock_fd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  1425. X    report_progress (report, "\nbuild_tcp_connection(): Could not create \
  1426. socket", TRUE),
  1427. X    exit(12);
  1428. X  if (! (hostentry = gethostbyname ("localhost")))
  1429. X    report_progress (report, "\nbuild_tcp_connection(): No such host", TRUE),
  1430. X    exit(13);
  1431. X  sin.sin_family = AF_INET;
  1432. X  sin.sin_port = htons (PORT);
  1433. X  memcpy ((char *) &sin.sin_addr.s_addr, (char *) hostentry->h_addr,
  1434. X      hostentry->h_length);
  1435. X  memset (sin.sin_zero, EOS, sizeof (sin.sin_zero));
  1436. X  if (connect (sock_fd, (struct sockaddr *) &sin, sizeof (struct sockaddr_in))
  1437. X      < 0)
  1438. X    report_progress (report, "\nbuild_tcp_connection(): Could not connect to \
  1439. port", TRUE),
  1440. X    exit (14);
  1441. X  return sock_fd;
  1442. X}
  1443. X
  1444. X/*
  1445. X  Queue up a file for later delivery.
  1446. X*/
  1447. X
  1448. void queue_up (char *file)
  1449. X{
  1450. X  FILE *id;
  1451. X  int id_no = 0;
  1452. X  char msg [MAX_LINE];
  1453. X
  1454. X  if ((id = fopen (IDF, "r")) != NULL)
  1455. X    fscanf (id, "%d\n", &id_no),
  1456. X    fclose (id);
  1457. X  syscom ("mv %s %s/%d", file, QUEUE_DIR, ++id_no);
  1458. X  syscom ("echo %d > %s", id_no, IDF);
  1459. X  sprintf (msg, "File %s placed in the mail queue", file);
  1460. X  report_progress (report, msg, TRUE);
  1461. X}
  1462. END_OF_FILE
  1463. if test 6501 -ne `wc -c <'src/sysmail.c'`; then
  1464.     echo shar: \"'src/sysmail.c'\" unpacked with wrong size!
  1465. fi
  1466. # end of 'src/sysmail.c'
  1467. fi
  1468. if test -f 'src/sysmail.h' -a "${1}" != "-c" ; then 
  1469.   echo shar: Will not clobber existing file \"'src/sysmail.h'\"
  1470. else
  1471. echo shar: Extracting \"'src/sysmail.h'\" \(6146 characters\)
  1472. sed "s/^X//" >'src/sysmail.h' <<'END_OF_FILE'
  1473. X/*
  1474. X  AGREEMENT: This software can be used and distributed freely as long
  1475. X  as you do not remove or alter the Copyright notice in the file defs.h;
  1476. X  this notice is #define'd in the symbol VERSION. Although you may alter
  1477. X  the code provided, you may not alter the functions create_header()
  1478. X  and create_multi_recipient_header() in list.c and listserv.c.
  1479. X  By using this software you are bound by this agreement.
  1480. X  This software comes with no warranties and cannot be sold for profit.
  1481. X  The AGREEMENT and COPYRIGHT notices should be included in all source
  1482. X  files when distributing this software.
  1483. X  COPYRIGHT: Copyright (c) 1991, Anastasios C. Kotsikonas
  1484. X*/
  1485. X
  1486. X#define PORT          25
  1487. X#define TIMEOUT          10
  1488. X#define MAX_CALLS      1
  1489. X#define SENT          PATH/sent"
  1490. X#define RECEIVED      PATH/received"
  1491. X#define IDF          PATH/.queue.id"
  1492. X#define QUEUE_DIR      PATH/mqueue"
  1493. X
  1494. X/* List of SMTP commands recognized */
  1495. X
  1496. X#define ACKNOWLEDGE      220
  1497. X#define CLOSE_CONNECTION  221
  1498. X#define OK                250
  1499. X#define WILL_FORWARD      251
  1500. X#define DATA          354
  1501. X#define SERVICE_UNAVAIL      421
  1502. X#define PERMISSION_DENIED 450
  1503. X#define HOST_ABORTED      451
  1504. X#define DISK_FULL      452
  1505. X#define NOT_RECOGNIZED    500
  1506. X#define SYNTAX_ERROR      501
  1507. X#define BAD_SEQUENCE      503
  1508. X#define USER_UNKNOWN      550
  1509. X#define USER_NOT_LOCAL    551
  1510. X#define TOO_MUCH_DATA      552
  1511. X#define USER_AMBIGUOUS    553
  1512. X#define TRANS_FAILED        554
  1513. X#define END_OF_TEXT      ".\n"
  1514. X
  1515. X#define CLOSEF \
  1516. X  fclose (msg),\
  1517. X  close (sock_fd)
  1518. X
  1519. X#define NOTIFY_MANAGER \
  1520. X  if (sys.options & BSD_MAIL)\
  1521. X    syscom ("%s -s \"Error during message delivery: check the report \
  1522. files\" %s &", UCB_MAIL, sys.manager);\
  1523. X
  1524. X#define WARN_MANAGER \
  1525. X  if (sys.options & BSD_MAIL)\
  1526. X    syscom ("%s -s \"Warning during message delivery: check the report \
  1527. files\" %s &", UCB_MAIL, sys.manager);\
  1528. X
  1529. X#define ABORT_CONNECTION \
  1530. X  if (write (sock_fd, "QUIT\n", 5) < 5)\
  1531. X    report_progress (report, "_sysmail(): WARNING: Error writing to \
  1532. socket, while closing connection", TRUE);\
  1533. X  if (debug)\
  1534. X    fprintf (sent, "QUIT\n"),\
  1535. X    fflush (sent);\
  1536. X  cmd = server_response (sock_fd, report);
  1537. X
  1538. X#define PROTOCOL(arg) \
  1539. X  while (!feof (msg) && cmd != arg) {\
  1540. X    RESET (buf);\
  1541. X    fgets (buf, MAX_LINE - 2, msg);\
  1542. X    if (write (sock_fd, buf, strlen (buf)) < strlen (buf))\
  1543. X      report_progress (report, "_sysmail(): WARNING: Error writing to \
  1544. socket, trying again", TRUE);\
  1545. X    if (debug)\
  1546. X      fprintf (sent, "%s", buf),\
  1547. X      fflush (sent);\
  1548. X    cmd = server_response (sock_fd, report);\
  1549. X    timeout = 0;\
  1550. X    while (cmd != OK && cmd != arg && timeout < TIMEOUT) {\
  1551. X      ++timeout;\
  1552. X      if (write (sock_fd, buf, strlen (buf)) < strlen (buf))\
  1553. X    report_progress (report, "_sysmail(): WARNING: Error rewriting to \
  1554. socket", TRUE);\
  1555. X      if (debug)\
  1556. X        fprintf (sent, "%s", buf),\
  1557. X        fflush (sent);\
  1558. X      cmd = server_response (sock_fd, report);\
  1559. X    }\
  1560. X    if (timeout == TIMEOUT) {\
  1561. X      char error [1024];\
  1562. X      if (cmd == SYNTAX_ERROR || cmd == TRANS_FAILED ||\
  1563. X          cmd == NOT_RECOGNIZED) {\
  1564. X        sprintf (error, "_sysmail(): Command: %snot recognized by sendmail.\
  1565. X\n%s\nCould not deliver mail", buf, message);\
  1566. X        report_progress (report, error, TRUE);\
  1567. X        NOTIFY_MANAGER;\
  1568. X    ABORT_CONNECTION;\
  1569. X        CLOSEF;\
  1570. X        exit (15);\
  1571. X      }\
  1572. X      else if (cmd == BAD_SEQUENCE) {\
  1573. X        sprintf (error, "_sysmail(): Command: %sissued too soon.\
  1574. X\n%s\nCould not deliver mail", buf, message);\
  1575. X        report_progress (report, error, TRUE);\
  1576. X        NOTIFY_MANAGER;\
  1577. X    ABORT_CONNECTION;\
  1578. X        CLOSEF;\
  1579. X        exit (15);\
  1580. X      }\
  1581. X      else if (cmd == SERVICE_UNAVAIL || cmd == HOST_ABORTED) {\
  1582. X        sprintf (error, "_sysmail(): Service unavailable.\
  1583. X\n%s\nCould not deliver mail", message);\
  1584. X        report_progress (report, error, TRUE);\
  1585. X        NOTIFY_MANAGER;\
  1586. X    ABORT_CONNECTION;\
  1587. X    queue = TRUE;\
  1588. X    goto abort;\
  1589. X      }\
  1590. X      else if (cmd == DISK_FULL) {\
  1591. X    sprintf (error, "_sysmail(): File system full.\n%s\nCould not \
  1592. deliver mail", message);\
  1593. X        report_progress (report, error, TRUE);\
  1594. X        NOTIFY_MANAGER;\
  1595. X    ABORT_CONNECTION;\
  1596. X        queue = TRUE;\
  1597. X        goto abort;\
  1598. X      }\
  1599. X      else if (cmd == TOO_MUCH_DATA) {\
  1600. X        sprintf (error, "_sysmail(): Too many recipients or message \
  1601. too long.\n%s\nCould not deliver mail", message);\
  1602. X        report_progress (report, error, TRUE);\
  1603. X        NOTIFY_MANAGER;\
  1604. X    ABORT_CONNECTION;\
  1605. X        CLOSEF;\
  1606. X        exit (15);\
  1607. X      }\
  1608. X      else if (cmd == USER_UNKNOWN) {\
  1609. X    sprintf (error, "_sysmail(): Address: %snot recognized.\n%s\nMessage \
  1610. not delivered to this recipient", buf, message);\
  1611. X        report_progress (report, error, TRUE);\
  1612. X    WARN_MANAGER;\
  1613. X        continue;\
  1614. X      }\
  1615. X      else if (cmd == USER_NOT_LOCAL) {\
  1616. X        sprintf (error, "_sysmail(): Address: %snot local; %s", buf, message);\
  1617. X        report_progress (report, error, TRUE);\
  1618. X        WARN_MANAGER;\
  1619. X        continue;\
  1620. X      }\
  1621. X      else if (cmd == USER_AMBIGUOUS) {\
  1622. X        sprintf (error, "_sysmail(): Address ambiguous: %s%s\nMessage not \
  1623. delivered to this address", buf, message);\
  1624. X        report_progress (report, error, TRUE);\
  1625. X        WARN_MANAGER;\
  1626. X        continue;\
  1627. X      }\
  1628. X      else if (cmd == PERMISSION_DENIED) {\
  1629. X        sprintf (error, "_sysmail(): Permission denied for address %s%s\n\
  1630. Message not delivered to this recipient", buf, message);\
  1631. X        report_progress (report, error, TRUE);\
  1632. X        WARN_MANAGER;\
  1633. X        continue;\
  1634. X      }\
  1635. X      else if (cmd == WILL_FORWARD) {\
  1636. X    sprintf (error, "_sysmail(): Address: %snot local; %s", buf, message);\
  1637. X        report_progress (report, error, TRUE);\
  1638. X        WARN_MANAGER;\
  1639. X        continue;\
  1640. X      }\
  1641. X      sprintf (error, "_sysmail(): ERROR: Return value %d for command: %s%s\n\
  1642. Please notify tasos@cs.bu.edu", cmd, buf, message);\
  1643. X      report_progress (report, error, TRUE);\
  1644. X      NOTIFY_MANAGER;\
  1645. X      if (call < MAX_CALLS)\
  1646. X    CLOSEF,\
  1647. X        sleep (60),\
  1648. X    _sysmail (file, call + 1);\
  1649. X      report_progress (report, "_sysmail(): ERROR: Could not deliver mail", \
  1650. TRUE);\
  1651. X      CLOSEF,\
  1652. X      exit (15);\
  1653. X    }\
  1654. X  }
  1655. X
  1656. static char message [1024];
  1657. static FILE *sent, *received;
  1658. static BOOLEAN queue;
  1659. END_OF_FILE
  1660. if test 6146 -ne `wc -c <'src/sysmail.h'`; then
  1661.     echo shar: \"'src/sysmail.h'\" unpacked with wrong size!
  1662. fi
  1663. # end of 'src/sysmail.h'
  1664. fi
  1665. echo shar: End of archive 2 \(of 6\).
  1666. cp /dev/null ark2isdone
  1667. MISSING=""
  1668. for I in 1 2 3 4 5 6 ; do
  1669.     if test ! -f ark${I}isdone ; then
  1670.     MISSING="${MISSING} ${I}"
  1671.     fi
  1672. done
  1673. if test "${MISSING}" = "" ; then
  1674.     echo You have unpacked all 6 archives.
  1675.     rm -f ark[1-9]isdone
  1676. else
  1677.     echo You still need to unpack the following archives:
  1678.     echo "        " ${MISSING}
  1679. fi
  1680. ##  End of shell archive.
  1681. exit 0
  1682.